/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package im.clusterhead;

import im.eventpackage.Event;
import im.general.AbstractListenBehaviour;
import im.general.Config;
import im.messages.ResourceMessage;
import im.node.MobileNodeInfo;
import im.resources.ResourceStatus;
import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;
import jade.wrapper.ControllerException;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author brownstone
 */
public class UpdateStatusListenBehaviour extends AbstractListenBehaviour{

    ClusterHeadAgent clusterHeadAgent;

    public UpdateStatusListenBehaviour(ClusterHeadAgent clusterHeadAgent) {
        this.clusterHeadAgent = clusterHeadAgent;
        mt = MessageTemplate.MatchEncoding(Config.UPDATE_STATUS_NAME);
    }
    @Override
    protected void handleMessage(ACLMessage msg) {
        try {
            ResourceMessage resourceMessage = null;
            try {
                resourceMessage = (ResourceMessage) msg.getContentObject();
            } catch (UnreadableException ex) {
                Logger.getLogger(UpdateStatusListenBehaviour.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            String node = msg.getSender().getName();

            //mancava -> Dan
            //this.clusterHeadAgent.setNodeStatus(node,resourceMessage.getResourceStatus() );

            
            if (resourceMessage.getContainerID().equals(clusterHeadAgent.getContainerController().getContainerName()) ){
                handleStatusUpdate(node, resourceMessage.getResourceStatus());
                handleMyStatusUpdate(resourceMessage.getResourceStatus());
                return;
            } else {
                handleStatusUpdate(node, resourceMessage.getResourceStatus());
            }
        } catch (ControllerException ex) {
            Logger.getLogger(UpdateStatusListenBehaviour.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void handleMyStatusUpdate(ResourceStatus resourceStatus) {
        if(clusterHeadAgent.myMNguestAgent.equals(Config.EVENT_SERVICE_NAME))
            return;

        if(resourceStatus.isLow()) {
            Enumeration names = clusterHeadAgent.getNodeNames();
            Enumeration infos = clusterHeadAgent.getNodeInfos();
            String name, maxName=null;
            MobileNodeInfo info, maxInfo=null;

            if(!names.hasMoreElements())
                return;
            while(names.hasMoreElements()&&infos.hasMoreElements()) {
                name=(String) names.nextElement();
                info=(MobileNodeInfo) infos.nextElement();
                //System.out.println("TRYING\t"+info.getResourceStatus());
                //if((maxInfo == null || !info.hasMoreResources(maxInfo)) && !info.getResourceStatus().getContainer().equals(clusterHeadAgent.getContainerName())){
                if((info != null && info.getResourceStatus().isBetter(resourceStatus) && info.hasMoreResources(maxInfo)) && !info.getResourceStatus().getContainer().equals(clusterHeadAgent.getContainerName())){
                    maxInfo = info;
                    maxName = name;
                }
            }
            
            if(maxInfo==null || maxName.equals(clusterHeadAgent.myMNguestAgent) || maxInfo.getResourceStatus().getStatusIndex()==0)
                return;

            //System.out.println("BETTER HOST\t"+this.clusterHeadAgent.myMNguestAgent + " " +resourceStatus.toString()+"\t->\t"+maxName + " " + clusterHeadAgent.getNodeInfo(maxName).getResourceStatus().getStatusIndex());//maxInfo.getResourceStatus().toString());

            //clusterHeadAgent.moveAgent(maxInfo.getResourceStatus().getContainer(), maxName);
            clusterHeadAgent.addBehaviour(new MoveBehaviour(clusterHeadAgent, maxInfo.getResourceStatus().getContainer(), maxName));
        }
    }
    // TODO trovata eccezione:
    /*
***  Uncaught Exception for agent CH_06  ***
java.util.NoSuchElementException: Hashtable Enumerator
ERROR: Agent CH_06 died without being properly terminated !!!
        at java.util.Hashtable$EmptyEnumerator.nextElement(Hashtable.java:1073)
State was 2
        at im.clusterhead.UpdateStatusListenBehaviour.handleMyStatusUpdate(UpdateStatusListenBehaviour.java:68)
        at im.clusterhead.UpdateStatusListenBehaviour.handleMessage(UpdateStatusListenBehaviour.java:52)
        at im.general.AbstractListenBehaviour.action(AbstractListenBehaviour.java:39)
        at jade.core.behaviours.Behaviour.actionWrapper(Behaviour.java:340)
        at jade.core.Agent$ActiveLifeCycle.execute(Agent.java:1530)
        at jade.core.Agent.run(Agent.java:1468)
        at java.lang.Thread.run(Thread.java:595)
*/


    private void handleStatusUpdate(String node, ResourceStatus resourceStatus) {
        //MobileNodeInfo info = clusterHeadAgent.getNodeInfo(node);
        //info.setResourceStatus(resourceStatus);
        //clusterHeadAgent.setNodeInfo(node, info);
        clusterHeadAgent.setResourceStatus(node, resourceStatus);
        //System.out.println("UPDATED HASH TABLE: " + clusterHeadAgent.getNodes().toString());
    }

}
